using System.Dynamic;
using System.Reflection;

namespace Core.Db.Helper;

public static class IEnumerableExtensions
{
    public static IEnumerable<ExpandoObject> ShapeData<TSource>(this IEnumerable<TSource> source, string fields)
    {
        if (source == null)
        {
            throw new ArgumentNullException(nameof(source));
        }

        var expandoObjectList = new List<ExpandoObject>();
        //避免在列表中遍历数据，创建一个车属性信息列表
        var propertyInfoList = new List<PropertyInfo>();

        if (string.IsNullOrWhiteSpace(fields))
        {
            var propretyInfos = typeof(TSource).GetProperties(BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
            propertyInfoList.AddRange(propretyInfos);
        }
        else
        {
            var fieldsAfterSplit = fields.Split(',');
            foreach (var filed in fieldsAfterSplit)
            {
                //去掉首尾多余的空格,获取属性名称
                var propertyName = filed.Trim();
                var propertyInfo = typeof(TSource).GetProperty(propertyName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
                if (propertyInfo == null)
                {
                    throw new Exception($"属性{propertyName}找不到 {typeof(TSource)}");
                }

                propertyInfoList.Add(propertyInfo);
            }
        }

        foreach (TSource sourceObject in source)
        {
            //创建动态类型对象，创建数据塑性对象
            var dataShapedObject = new ExpandoObject();
            foreach (var propertyInfo in propertyInfoList)
            {
                //获得对应属性的真实数据
                var propertyValue = propertyInfo.GetValue(sourceObject);
                ((IDictionary<string,object>)dataShapedObject).Add(propertyInfo.Name,propertyValue);
            }
            
            expandoObjectList.Add(dataShapedObject);
        }

        return expandoObjectList;
    }
}